package com;

import org.openjdk.jcstress.annotations.Actor;
import org.openjdk.jcstress.annotations.JCStressTest;
import org.openjdk.jcstress.annotations.Outcome;
import org.openjdk.jcstress.annotations.State;
import org.openjdk.jcstress.infra.results.II_Result;

//import java.lang.invoke.MethodHandles;
//import java.lang.invoke.VarHandle;
//
//import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE;
//import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE_INTERESTING;
//
//@JCStressTest
//@State
//@Outcome(id = {"0, 0", "1, 1"}, expect = ACCEPTABLE, desc = "Boring wngb")
//@Outcome(id = "0, 1", expect = ACCEPTABLE, desc = "In order wngb")
//@Outcome(id = "1, 0", expect = ACCEPTABLE_INTERESTING, desc = "Whoa wngb")
//public class Adv {
//
//    private int x, y;
//
//    /*
//      ----------------------------------------------------------------------------------------------------------
//
//         This is the first example that shows the advanced things in JMM. Most of these examples show
//         what JMM is *not*, rather that what JMM *is*.
//
//         It is easy to read "JSR 133 Cookbook for Compiler Writers" and get a wrong idea that the conservative
//         implementation that JSR 133 Cookbook provides as the implementation guidance is the memory
//         model as specified. For example, it is a common mistake to assume that synchronized blocks
//         have barriers associated with them.
//
//         In this example,
//         we do two back-to-back synchronized blocks in one thread,
//         and read the updates in the other thread with the maximum ordering possible, "volatile".
//
//         If synchronized blocks indeed provided the barriers,
//         then it would not be possible to write "x" and "y" out of order, and
//         therefore, "1, 0" outcome would be forbidden.
//
//         But in reality, even on x86_64, this test yields:
//
//              RESULT        SAMPLES     FREQ       EXPECT  DESCRIPTION
//                0, 0  3,815,999,238   92.96%   Acceptable  Boring
//                0, 1     10,345,809    0.25%   Acceptable  In order
//                1, 0        207,479   <0.01%  Interesting  Whoa
//                1, 1    278,646,578    6.79%   Acceptable  Boring
//
//         Technically, this is due to "lock coarsening" that merged the synchronized blocks, and then was able
//         to order the writes to "x" and "y" differently. JMM as stated allows this optimization: we are only
//         required to see these stores in order if we are synchronizing on the same "this". Side observers can
//         see the writes in whatever order.
//    */
//
//    static final VarHandle VH_X, VH_Y;
//
//    static {
//        try {
//            VH_X = MethodHandles.lookup().findVarHandle(Adv.class, "x", int.class);
//            VH_Y = MethodHandles.lookup().findVarHandle(Adv.class, "y", int.class);
//        } catch (NoSuchFieldException | IllegalAccessException e) {
//            throw new IllegalStateException(e);
//        }
//    }
//
//    @Actor
//    void actor() {
//        synchronized (this) {
//            x = 1;
//        }
//        synchronized (this) {
//            y = 1;
//        }
//    }
//
//    @Actor
//    void observer(II_Result r) {
//        r.r1 = (int) VH_Y.getVolatile(this);
//        r.r2 = (int) VH_X.getVolatile(this);
//    }
//}